#include "app_buffer.h"
#include "log/log.h"
#include <stdlib.h>
#include <string.h>
/** 
 * @function: 初始化缓冲区
 * @param: total_size 缓冲区大小
 * @return: 返回缓冲区指针
*/

static pthread_mutex_t buff_mutex = PTHREAD_MUTEX_INITIALIZER;


Buffer *app_buffer_init(int total_size){
    if (total_size <= 0)
    {
        log_error("total_size is invalid");
        return NULL;
    }
    //初始化buffer结构体空间
    Buffer *buffer = malloc(sizeof(Buffer));
    if (buffer == NULL){
        log_error("malloc buffer failed");
        return NULL;
    }
    //初始化缓冲区ptr属性大小
    buffer->ptr = malloc(total_size);
    if (buffer->ptr == NULL){
        log_error("malloc buffer->ptr failed");
        free(buffer);

        //初始化互斥锁
        buffer->mutex = buff_mutex;
        return NULL;
    }

    buffer->total_size = total_size;
    buffer->len = 0;
    buffer->offset = 0;
    return buffer;
}

/**
 * @function: 释放缓冲区
 * @param: buffer 缓冲区指针
 */
void app_buffer_free(Buffer *buffer){
    if (buffer==NULL)
    {
        log_error("buffer is NULL");
        return;
    }
    free(buffer->ptr);
    free(buffer);
}

/**
 * @function: 向缓冲区写入数据
 * @param: buffer 缓冲区指针
 * @param: data 写入数据
 * @param: len 写入数据长度
 * @return: 返回0为成功，返回-1为失败
 */
int app_buffer_write(Buffer *buffer,char *data,int len){

    if (buffer == NULL || data == NULL || len <= 0)
    {
        log_error("buffer or data or len is invalid");
        return -1;
    }
    
    pthread_mutex_lock(&buffer->mutex);

    if(len>buffer->total_size-buffer->len){
        log_error("buffer is full");
        return -1;
    }
    int write_start = buffer->offset + buffer->len;
    if(write_start >= buffer->total_size){
        write_start -= buffer->total_size;
    }

    //判断需要一次写还是两次写
    if(write_start + len < buffer->total_size){
        memcpy(buffer->ptr+write_start,data,len);
    }else{
        //计算第一次长度
        int len1 = buffer->total_size-write_start;
        //写入第一段
        memcpy(buffer->ptr+write_start,data,len1);
        //写入第二段
        memcpy(buffer->ptr,data+len1,len-len1);
    }
    buffer->len += len;

    pthread_mutex_unlock(&buffer->mutex);

    log_debug("buffer write success len:%d,buffer-ptr:%s,offset:%d,len:%d",len,data,buffer->offset,buffer->len);
    return 0;
}

/**
 * @function: 从缓冲区读取数据
 * @param: buffer 缓冲区指针
 * @param: data 读取数据的容器
 * @param: len 读取数据长度
 * @return: 返回读取的数据0成功-1失败
 */
int app_buffer_read(Buffer *buffer,char *data,int len){
    if (buffer == NULL || data == NULL || len <= 0)
    {
        log_error("buffer or data or len is invalid");
        return -1;
    }
    pthread_mutex_lock(&buffer->mutex);

    if(len>buffer->len){
        log_error("buffer里数据不足");
        return -1;
    }
    if(buffer->total_size - buffer->offset >= len){
        memcpy(data,buffer->ptr+buffer->offset,len);
        buffer->offset += len;
    }else{
        int len1 = buffer->total_size - buffer->offset;
        //读取第一段
        memcpy(data,buffer->ptr+buffer->offset,len1);
        //读取第二段
        memcpy(data+len1,buffer->ptr,len-len1);
        buffer->offset = len-len1;
    }
    buffer->len -= len;
    pthread_mutex_unlock(&buffer->mutex);

    log_debug("buffer read success len:%d,buffer-ptr:%s,offset:%d,len:%d",len,data,buffer->offset,buffer->len);

    return 0;
}

